/ 读书笔记  

Golang 学习之旅 --- 基础知识

1.并发和并行的区别

并发 (concurrency):指两个或多个任务在同一时间段内启动运行并结束,并且这些任务可能会互动。
以并发形式执行的多个任务会同时存在,这跟顺序执行每次只会存在一个任务的情况正好相反。

并行 (parallelism):在并行中,多个任务将同时启动并执行。并行通过把一个大任务分割成多个更小的任务,然后通过同时执行这些小任务来提高性能。并行通常需要独立的资源(如CPU),而并发则会使用和分享相同的资源。

并发指的是同时处理多项任务,而并行指的是同时执行多项任务。

2.goroutine

goroutine指的是那些独立于其它 goroutine运行的函数。这一个概念看上去和线程有些相似,但实际上 goroutine并不是线程,它只是对线程的多路复用。因为 goroutine都是轻量级的,所以goroutine的数量可以比线程的数量多很多。一个 goroutine在启动时只需要一个非常小的栈,并且这个栈可以按需扩展和缩小。当一个 goroutine被阻塞时,它也会阻塞所复用的操作系统线程,而运行时环境(runtime)则会把位于被阻塞线程上的其它 groutine移动到其它未阻塞的线程上继续运行。

3.信道

信道就像一个箱子,不同的 goroutine可以通过这个箱子与其它 goroutine通信。
信道(channel)是一种带有类型的值,它可以让不同的goroutine互相通信。信道用make函数创建,该函数在被调用之后将返回一个指向底层数据结构的引用作为结果值。

创建一个整数组成的信道:
ch := make(chan int)

通过信道实现消息传递:

4.对Web应用的理解

一个程序只需要满足以下两个条件,就可以看作是一个 Web应用:
a.这个程序必须向发送命令请求的客户端返回HTML,而客户端则会向用户展示渲染后的HTML;
b.这个程序向客户端传送数据时必须使用HTTP协议

在这个定义的基础上,如果一个程序不是向用户渲染并展示HTML,而是向其它程序返回某种非HTML格式的数据,那么这个程序就是一个为其它程序提供服务的Web服务。

Web应用最基本的请求与相应结构:

5.HTTP

HTTP是万维网的应用层通讯协议,Web应用中的所有数据都是通过这个看似简单的文本协议进行传输的。

HTTP是一种无状态协议,它唯一知道的就是客户端会向服务器发送请求,而服务器会向客户端返回响应,并且后续发生的请求对之前发生过的请求一无所知。

请求 - 响应是两台计算机进行通信的基本方式,其中一台计算机会向另一台计算机发送请求,而接收到请求的计算机则会对请求进行响应。在客户端 - 服务器计算模型中,发送请求的一方(客户端) 负责向返回响应的一方 (服务器) 发起会话,而服务器则负责向客户端提供服务。在HTTP协议中,客户端也被称作用户代理(user-agent),而服务器通常会被称为Web服务器。在大多数情况下,HTTP客户端都是一个Web浏览器。

6.HTTP请求

HTTP是一种请求 - 响应协议,协议涉及的所有事情都以一个请求开始。HTTP请求和所有的HTTP报文一样,都由一系列文本行组成,并以以下顺序排列:
(1)请求行 (request-line)
(2)零个或多个请求首部(header)
(3)一个空行
(4)可选的报文主体(body)

GET /Protocols/rfc2616/rfc2616.html HTTP/1.1
Host: www.w3.org
User-Agent: Mozilla/5.0
(empty line)

7.各种HTTP方法

GET
HEAD
POST
PUT
DELETE
TRACE
OPTIONS
CONNECT
PATCH

8.安全的请求方法

如果一个 HTTP方法只要求服务器提供信息而不会对服务器的状态做任何修改,那么这个方法就是安全的。

9.幂等的概念

如果一个HTTP方法在使用相同的数据进行第二次调用的时候,不会对服务器的状态作出任何改变,那么这个方法就是幂等的。PUT和DELETE方法虽然不安全,但也是幂等的。

10.请求首部

HTTP请求方法定义了发送请求的客户端想要执行的操作,而 HTTP请求首部则记录了与请求本身以及客户端相关的信息。

11.URL

Uniform Resource Identifier 统一资源标识符 URI
Uniform Resource Location 统一资源定位符 URL

12.Web应用组成部分

Web应用可以被分为处理器(handler)和模版引擎(template engine)两个部分。

13.处理器的作用

Web应用中的处理器除了要接收和处理客户端发来的请求,还需要调用模版引擎,然后由模版引擎生成 HTML并把数据填充至将要返回给客户端的响应报文当中。

14.动态模版和静态模版

动态模版里包含一些编程语言结构,如条件语句,迭代语句和变量。而静态模版是一些夹杂着占位符的HTML,通常不包含任何逻辑代码。

15.服务器在 Web应用中的工作流程

16.数据模型

数据模型里包含一些数据结构,比如以下四种数据结构:
a.User
b.Session
c.Thread
d.Post

数据结构会被映射到关系数据库里,并与数据库交互

17.请求的接收与处理

请求的接收和处理是所有Web应用的核心。Web应用的工作流程如下:
(1)客户端将请求发送到服务器的一个URL上
(2)服务器的多路复用器将接收到的请求重定向到正确的处理器,然后由该处理器对请求进行处理。
(3)处理器处理请求并执行必要的动作
(4)处理器调用模版引擎,生成相应的HTML并将其返回给客户

18.处理器函数的概念

处理器函数是一种接收ResponseWriter和Request指针作为参数的 Go函数

func index(w http.ResponseWriter, r *http.Request) {
files := []string{“templates/layout.html”,
“templates/navbar.html”,
“templates/index.html”,}
templates := template.Must(template.ParseFiles(files…))
threads, err := data.Threads(); if err == nil {
templates.ExecuteTemplate(w, “layout”, threads)
}
}

19.常用的处理器函数

func handler(writer http.ResponseWriter, request *http.Request) {
fmt.Fprintf(writer, “Hello World, %s!”, request.URL.Path[1:])
}

handler在特定事件被触发后,负责对事件进行处理的回调函数。
第一个参数是 ResponseWriter接口,第二个参数是指向 Request结构的指针。
handler函数会从 Request结构中提取相应的信息,然后创建一个HTTP响应,最后通过 ResponseWriter接口将响应返回给客户端。

20.使用Cookie进行访问控制

因为HTTP是无状态协议,所以需要Cookie来标记状态,进行访问控制。

“以Cookie的方式在客户端实现数据持久化,并以会话的方式在服务器上实现数据持久化。”

21.HTML

超文本标记语言(Hypertext Marked Language),用来制作超文本文档的简单标记语言。

用HTML编写的超文档称为HTML文档,超文本意味着可以加入图片,声音,动画等内容。
事实上每一个HTML文档都是一种静态的网页文件,这个文件里包含了HTML指令代码,这些代码并不是一种程序语言,只是一种排版网页中资料显示位置的标记语言。

22.Go切片

Go的切片为处理同类型数据排列提供了一个方便且高效的方式,切片有些类似于其它语言中的数组。
Go中的数组的长度不可改变,在特定场景中这样的集合就不太适用。切片和数组相比长度不固定,可以追加元素,在追加时可能使切片的容量增大。

切片中有两个概念: 长度(len)和容量(cap)。长度指已经被赋过值的最大下标+1,可以通过内置函数len()获得。容量是指切片目前可容纳的最多元素个数,可以通过内置函数cap()获得。

切片是引用类型,因此在传递切片时将引用同一指针,修改值将会影响其他的对象。

23.空接口类型

参数的类型为空接口类型,这说明参数可以接受任何类型的值作为输入。

24.对数据库进行操作

Db是一个全局变量,这个全局变量是一个指针,指向的是代表数据库连接池的sql.DB。后续的代码会使用这个Db变量来执行数据库查询操作。

var Db *sql.DB
func init() {
var err error
Db, err = sql.Open(“postgres”, “dbname=chitchat simone=disable”)
if err != nil {
log.Fatal(err)
}
return
}

25.数据层

在处理器函数和数据库中间,需要一个数据层,来避免处理器函数直接对数据库进行访问。

26.通过数据模型连接数据库和处理器

27.Web应用的工作流程

(1)客户端向服务器发送请求;
(2)多路复用器接收到请求,将其重定向到正确的处理器;
(3)处理器对请求进行处理;
(4)在需要访问数据库的情况下,处理器会使用一个或多个数据结构,这些数据结构都是根据数据库中的数据建模而来的;
(5)当处理器调用与数据结构有关的函数或方法时,这些数据结构背后的模型会与数据库进行连接,并执行相应的操作;
(6)当请求处理完毕时,处理器会调用模版引擎,有时候还会向模版引擎传递一些通过模型获取到的数据;
(7)模版引擎会对模版文件进行语法分析并创建相应的模版,而这些模版又会与处理器传递的数据一起合并生成最终的HTML;
(8)生成的HTML会作为相应的一部分回传至客户端。

28.HTTPS

即SSL之上的 HTTP,实际上就是在 SSL/TSL连接的上层进行HTTP通信。
SSL(Secure Sockets Layer 安全套接层)
TLS (Transport Layer Security 传输层安全协议)

29.服务器

在 Go语言中,一个处理器就是一个拥有 ServeHTTP方法的接口,这个ServeHTTP方法需要接收两个参数: ResponseWriter接口和指向Request结构的指针。

处理器的定义也可以理解为:任何一个接口只要拥有一个 ServeHTTP方法,并且该方法带有以下签名(signature),那么这个接口就是一个处理器。

30.DefaultServeMux

多路复用器 DefaultServeMux是 ServeMux结构的一个实例,同时也是 Handler的实例,因此它不仅是一个多路复用器,还是一个特殊的处理器。唯一要做的就是根据请求的URL将请求重定向到不同的处理器。

31.处理器函数

处理器函数其实就是和处理器拥有相同行为的函数,这些函数与 ServeHTTP方法拥有相同的签名,它们接收 ResponseWrite和指向 Request结构的指针作为参数。
处理器函数就是创建处理器的一种更便捷的方法。

32.管道管理

串联起两个函数的方法称为管道管理,串联多个函数可以让程序执行更多的动作。
函数式编程可以把一个函数传递给另外一个函数,将两个函数串联起来。

33.ServeMux

是一个HTTP请求多路复用器,负责接收 HTTP请求并根据请求中的 URL将请求重新定向到正确的处理器。当用户没有为 Serve结构指定处理器时,服务器就会使用 DefaultServeMux作为ServeMux的默认实例。

ServeMux是一个结构而不是接口,DefaultServeMux是 ServeMux的一个实例。

34.HTTP报文

HTTP报文是在客户端和服务器之间传递的消息,分为HTTP请求和HTTP响应两种类型,并且这两种类型的报文都拥有相同的结构。
(1)请求行或者响应行
(2)零个或多个首部
(3)一个空行
(4)一个可选的报文主体

GET /Protocols/rfc2616/ftc2616.html HTTP/1.1
Host: www.w3.org
User-Agent: Mozilla/5.0
(empty line)

35.Request结构

a.URL字段;
b.Header字段;
c.Body字段;
d.Form字段 PostForm字段和MultipoarForm字段

36.使用 Request结构的方法获取表单数据的一般步骤

a.调用ParseForm方法或者ParseForm方法,对请求进行语法分析
b.根据步骤a调用的方法,访问相应的Form字段 PostForm字段或MultipartForm字段

37.func index(w http.ResponseWriter, r *http.Request)里的 ResponseWriter

ResponseWriter是一个接口,处理器可以通过这个接口创建HTTP响应。ResponseWriter在创建响应时会用到http.response结构,因为该结构是一个非导出(nonexported)的结构,所以用户只能通过ResponseWriter来使用这个结构,而不能直接使用它

ResponseWriter接口拥有以下3个方法: Write WriteHeader和Header

服务器通过向 ResponseWriter写入首部和主体来向客户端返回响应

cookie是一种存储在客户端的,体积较小的信息,这些信息最初都是由服务器通过 HTTP响应报文发送的。每当客户端向服务器发送一个 HTTP请求时,cookie都会随着请求被一同发送至服务器。cookie的设计本意是要克服HTTP的无状态性,虽然cookie并不是完成这一目的的唯一方法,但却是最常用的流行方法之一。

39.Go语言Cookie的结构

type Cookie struct {
Name string
Value string
Path string
Domain string
Expires time.Time
RawExpires string
MaxAge int
Secure bool
HttpOnly bool
Raw string
Unparsed []string
}

40.闪现消息

闪现消息的意思是,当一个页面上的某个条件被满足的时候,页面上会显示一条临时出现的消息,这样用户在刷新页面之后就不会再看到相同的信息了。

这种临时出现的消息称为闪现消息(flash message)

实现闪现消息的方法有很多种,最常见的一种就是把这些消息存储在页面刷新时就会被移除的会话cookie里面。

41.模版和模版引擎

Web模版就是一些预先设计好的 HTML页面,模版引擎的代码会通过重复使用这些模版页面来创建一个或多个HTML页面。

模版引擎通过将数据和模版组合在一起来生成最终的HTML,而处理器负责调用模版引擎并将引擎生成的HTML返回给客户端

42.处理器调用模版引擎的流程:

处理器首先掉用模版引擎,接着以模版文件列表的方式向模版引擎传入一个或多个模版,然后再传入模版需要用到的动态数据;模版引擎在接收到这些参数之后会生成相应的HTML,并将这些文件写入到 ResponseWriter里面,然后由 ResponseWriter将 HTTP响应返回给客户端。

43.ParseFiles函数

可以对模版文件进行语法分析,并创建出一个经过语法分析的模版以供 Excute方法执行

44.Go里面的Panic

通过这种机制处理分析模版时可能产生的erorr:
t := template.Must(template.ParseFiles(“tmp.html”))
Must函数可以包裹起一个函数,被包裹的函数会返回一个指向模版的指针和一个错误,如果这个错误不为nil,那Must函数会产生一个panic。
Go里面的panic会导致正常的执行流程会终止:如果panic是在函数内部产生的,那么这个函数会将这个panic返回给它的调用者。panic会一直向调用栈的上方传递,知道main函数为止,并且程序也会因此崩溃。

45.Go模版里的动作

Go模版的动作就是一些嵌入在模版里的命令,在模版中使用两个大括号进行包围。包括:
a.条件动作
b.迭代动作
c.设置动作
d.包含动作
e.定义动作

(.)也是一个动作,并且是最重要的动作,代表的是传递给模版的数据,其它动作和函数基本都会对这个动作进行处理,以此达到格式化和内容展示的目的。

46.Web应用常用的存储手段

a.程序运行时,将数据存储在内存里
b.将数据存储在文件系统的文件里
c.通过服务器程序前端,将数据存储在数据库里

47.Go与SQL

如果需要在一个健壮并且可扩展的环境里存储数据,就需要转向使用数据库服务器。数据库服务器是一种程序,它可以让其它程序通过客户端-服务器模型(client-server model)来访问数据,并且这种访问只能通过数据库服务器实现,其它形式的访问则会被拒绝。通常情况下,客户端与数据库服务器进行连接,然后通过结构化查询语言(Structured query language, SQL)对数据进行访问。

48.handle 句柄

var Db *sql.DB
sql.DB结构是一个数据库句柄(handle),它代表的是一个包含了零个或任意多个数据库连接的连接池(pool),这个连接池由sql包管理。程序可以通过调用Open函数,并将相应的数据库驱动名字 (driver name)以及数据源名字 (data source name)传递给该函数来创建与数据库的连接。Open函数在执行后会返回一个指向sql.DB结构的指针作为结果。

句柄不是实际的连接,代表的是一个会自动对连接进行管理的连接池。

49.预处理语句

一条预处理语句就是一个SQL语句模版
使用sql.DB结构的Prepare方法来创建预处理语句:
stmt, err := db.Prepare(statement)
这行代码创建了一个指向sql.stmt接口的引用,这个引用就是上面提高的预处理语句。sql.stmt接口的定义位于sql.Driver包当中,而具体的结构则有数据库驱动实现。

50.关系型数据库

关系型数据库之所以能够成为一种流行的数据存储手段,其中一个原因就是它可以在表与表之间建立关系,从而使不同的数据能够以一种一直且易于理解的方式互相进行关联。基本上,有4种方法可以把一项纪录与其它纪录关联起来:
a.一对一关联,例如一个用户对应一个个人简介
b.一对多关联,例如一个用户可以拥有多篇论坛帖子
c.多对一关联,例如多篇论坛帖子可以同属某一个用户
d.多对多关联,例如一个用户可能参与多篇帖子的讨论,而一篇帖子里也会有多个用户发表评论

51.CURD

Creat 增加
Retrieve 读取查询
Update 更新
Delete 删除
是DataBase层或者持久层的基本操作功能

52.ORM

对象 - 关系映射器 (object-relational mapper)

53.并发和并行

并发和并行是两个相辅相成的概念,但它们并不相同。并发指的是两个或多个任务在同一时间段内启动,运行和结束,并且这些任务可能会彼此互动。而并行则是单纯的同时运行多个任务。

Go通过goroutine和通道这两个重要的特性直接支持并发,但Go并不直接支持并行。
Go Web服务器本身是并发的,服务器会把接收到的每条请求都放到独立的goroutine里运行。

54.select

select语句可以以先到先服务的方式,从多个通道里选出一个已经准备好执行接收操作的通道。
它允许用户从多个通道中选择一个通道来执行接收或者发送操作,select关键字就像专门为通道而设的switch语句。

55.等待goroutine完成

等待组(WaitGroup)可以解决程序比goroutine更早结束的问题:
a.声明一个等待组
b.使用Add方法为等待组的计数器设置值
c.当一个goroutine完成它的工作时,使用Done方法对等待组的计数器执行减一操作
d.调用Wait方法,该方法将一直阻塞,知道等待组计数器的值变为0

56.有缓冲通道

有缓冲通道就像是一个能容纳多个同类信息的大箱子: 一个goroutine可以持续地向箱子里面推入信息,并且在箱子被填满之前,推入信息的goroutine都不会被阻塞;同样的,另一个goroutine可以按照信息被推入的顺序,持续地从箱子里取出信息,并且在箱子被掏空之前,取出信息的goroutine都不会被阻塞。

57.基于REST的Web服务

REST(Representation State Transfer,具像状态传输)是一种设计理念,用于设计那些通过标准的几个动作来操纵资源,并以此来进行相互交流的程序。

在面向对象编程(OOP)范型中,通过创建称为对象(object)的模型来表示事物,然后定义称为方法(method)的函数并将它们附着到模型之上。REST是这种编程思想的进化版,但它并不是把函数暴露(expose)为可调用的服务,而是以资源(resource)的名义把模型暴露出来,并允许人们通过少数几个称为动词(verb)的动作来操纵这些资源。

在使用HTTP协议事项REST服务时,URL将用于表示资源,而HTTP方法则会用作操纵资源的动词,例如:

基于REST的Web服务通过HTTP协议向外界公开自己拥有的资源,并允许外界通过HTTP协议对这些资源执行指定的动作。

57.分析JSON

a.创建出用于存储JSON数据的结构
b.通过json.Unmarshal函数,把JSON数据解封道结构里面

将结构映射至JSON的规则: 对于名字为的JSON键,用户只需要在结构里创建一个任意名字的字段,并将该字段的结构标签设置为json:"name",就可以把JSON键的值存储到这个字段里面。

58.基于SOAP的Web服务

SOAP是一种协议,能否对定义在XML中的结构化数据进行交换。SOAP的WSDL报文很复杂。

创建和分析XML已经JSON的步骤都是相似的,用户要么根据指定的结构去生成XML或者JSON,要么从指定的结构里面提取数据到XML或者JSON里面。前一种称为封装,后一种操作称为解封。